#ifndef __FPGA_DECODER32_H__
#define __FPGA_DECODER32_H__

#include "graph_fpga.h"
#include <hls_math.h>
typedef struct shuffledData32 {
    uchar num;
    ap_uint<DECODE_SIZE*5> idx;
} shuffled_type32;
shuffled_type32 decode_function32(ap_uint<32> &opcode){
#pragma HLS INLINE
#pragma HLS PIPELINE
const unsigned int lutIdx1[256] = {
                0,
                268435456,
                268435457,
                536870944,
                268435458,
                536870976,
                536870977,
                805308448,
                268435459,
                536871008,
                536871009,
                805309472,
                536871010,
                805309504,
                805309505,
                1073842208,
                268435460,
                536871040,
                536871041,
                805310496,
                536871042,
                805310528,
                805310529,
                1073874976,
                536871043,
                805310560,
                805310561,
                1073876000,
                805310562,
                1073876032,
                1073876033,
                1073842208,
                268435461,
                536871072,
                536871073,
                805311520,
                536871074,
                805311552,
                805311553,
                1073907744,
                536871075,
                805311584,
                805311585,
                1073908768,
                805311586,
                1073908800,
                1073908801,
                1073842208,
                536871076,
                805311616,
                805311617,
                1073909792,
                805311618,
                1073909824,
                1073909825,
                1073874976,
                805311619,
                1073909856,
                1073909857,
                1073876000,
                1073909858,
                1073876032,
                1073876033,
                1073842208,
                268435462,
                536871104,
                536871105,
                805312544,
                536871106,
                805312576,
                805312577,
                1073940512,
                536871107,
                805312608,
                805312609,
                1073941536,
                805312610,
                1073941568,
                1073941569,
                1073842208,
                536871108,
                805312640,
                805312641,
                1073942560,
                805312642,
                1073942592,
                1073942593,
                1073874976,
                805312643,
                1073942624,
                1073942625,
                1073876000,
                1073942626,
                1073876032,
                1073876033,
                1073842208,
                536871109,
                805312672,
                805312673,
                1073943584,
                805312674,
                1073943616,
                1073943617,
                1073907744,
                805312675,
                1073943648,
                1073943649,
                1073908768,
                1073943650,
                1073908800,
                1073908801,
                1073842208,
                805312676,
                1073943680,
                1073943681,
                1073909792,
                1073943682,
                1073909824,
                1073909825,
                1073874976,
                1073943683,
                1073909856,
                1073909857,
                1073876000,
                1073909858,
                1073876032,
                1073876033,
                1073842208,
                268435463,
                536871136,
                536871137,
                805313568,
                536871138,
                805313600,
                805313601,
                1073973280,
                536871139,
                805313632,
                805313633,
                1073974304,
                805313634,
                1073974336,
                1073974337,
                1073842208,
                536871140,
                805313664,
                805313665,
                1073975328,
                805313666,
                1073975360,
                1073975361,
                1073874976,
                805313667,
                1073975392,
                1073975393,
                1073876000,
                1073975394,
                1073876032,
                1073876033,
                1073842208,
                536871141,
                805313696,
                805313697,
                1073976352,
                805313698,
                1073976384,
                1073976385,
                1073907744,
                805313699,
                1073976416,
                1073976417,
                1073908768,
                1073976418,
                1073908800,
                1073908801,
                1073842208,
                805313700,
                1073976448,
                1073976449,
                1073909792,
                1073976450,
                1073909824,
                1073909825,
                1073874976,
                1073976451,
                1073909856,
                1073909857,
                1073876000,
                1073909858,
                1073876032,
                1073876033,
                1073842208,
                536871142,
                805313728,
                805313729,
                1073977376,
                805313730,
                1073977408,
                1073977409,
                1073940512,
                805313731,
                1073977440,
                1073977441,
                1073941536,
                1073977442,
                1073941568,
                1073941569,
                1073842208,
                805313732,
                1073977472,
                1073977473,
                1073942560,
                1073977474,
                1073942592,
                1073942593,
                1073874976,
                1073977475,
                1073942624,
                1073942625,
                1073876000,
                1073942626,
                1073876032,
                1073876033,
                1073842208,
                805313733,
                1073977504,
                1073977505,
                1073943584,
                1073977506,
                1073943616,
                1073943617,
                1073907744,
                1073977507,
                1073943648,
                1073943649,
                1073908768,
                1073943650,
                1073908800,
                1073908801,
                1073842208,
                1073977508,
                1073943680,
                1073943681,
                1073909792,
                1073943682,
                1073909824,
                1073909825,
                1073874976,
                1073943683,
                1073909856,
                1073909857,
                1073876000,
                1073909858,
                1073876032,
                1073876033,
                1073842208
};

const unsigned int lutIdx2[256] = {
                0,
                268435464,
                268435465,
                536871208,
                268435466,
                536871240,
                536871241,
                805316904,
                268435467,
                536871272,
                536871273,
                805317928,
                536871274,
                805317960,
                805317961,
                1074112808,
                268435468,
                536871304,
                536871305,
                805318952,
                536871306,
                805318984,
                805318985,
                1074145576,
                536871307,
                805319016,
                805319017,
                1074146600,
                805319018,
                1074146632,
                1074146633,
                1074112808,
                268435469,
                536871336,
                536871337,
                805319976,
                536871338,
                805320008,
                805320009,
                1074178344,
                536871339,
                805320040,
                805320041,
                1074179368,
                805320042,
                1074179400,
                1074179401,
                1074112808,
                536871340,
                805320072,
                805320073,
                1074180392,
                805320074,
                1074180424,
                1074180425,
                1074145576,
                805320075,
                1074180456,
                1074180457,
                1074146600,
                1074180458,
                1074146632,
                1074146633,
                1074112808,
                268435470,
                536871368,
                536871369,
                805321000,
                536871370,
                805321032,
                805321033,
                1074211112,
                536871371,
                805321064,
                805321065,
                1074212136,
                805321066,
                1074212168,
                1074212169,
                1074112808,
                536871372,
                805321096,
                805321097,
                1074213160,
                805321098,
                1074213192,
                1074213193,
                1074145576,
                805321099,
                1074213224,
                1074213225,
                1074146600,
                1074213226,
                1074146632,
                1074146633,
                1074112808,
                536871373,
                805321128,
                805321129,
                1074214184,
                805321130,
                1074214216,
                1074214217,
                1074178344,
                805321131,
                1074214248,
                1074214249,
                1074179368,
                1074214250,
                1074179400,
                1074179401,
                1074112808,
                805321132,
                1074214280,
                1074214281,
                1074180392,
                1074214282,
                1074180424,
                1074180425,
                1074145576,
                1074214283,
                1074180456,
                1074180457,
                1074146600,
                1074180458,
                1074146632,
                1074146633,
                1074112808,
                268435471,
                536871400,
                536871401,
                805322024,
                536871402,
                805322056,
                805322057,
                1074243880,
                536871403,
                805322088,
                805322089,
                1074244904,
                805322090,
                1074244936,
                1074244937,
                1074112808,
                536871404,
                805322120,
                805322121,
                1074245928,
                805322122,
                1074245960,
                1074245961,
                1074145576,
                805322123,
                1074245992,
                1074245993,
                1074146600,
                1074245994,
                1074146632,
                1074146633,
                1074112808,
                536871405,
                805322152,
                805322153,
                1074246952,
                805322154,
                1074246984,
                1074246985,
                1074178344,
                805322155,
                1074247016,
                1074247017,
                1074179368,
                1074247018,
                1074179400,
                1074179401,
                1074112808,
                805322156,
                1074247048,
                1074247049,
                1074180392,
                1074247050,
                1074180424,
                1074180425,
                1074145576,
                1074247051,
                1074180456,
                1074180457,
                1074146600,
                1074180458,
                1074146632,
                1074146633,
                1074112808,
                536871406,
                805322184,
                805322185,
                1074247976,
                805322186,
                1074248008,
                1074248009,
                1074211112,
                805322187,
                1074248040,
                1074248041,
                1074212136,
                1074248042,
                1074212168,
                1074212169,
                1074112808,
                805322188,
                1074248072,
                1074248073,
                1074213160,
                1074248074,
                1074213192,
                1074213193,
                1074145576,
                1074248075,
                1074213224,
                1074213225,
                1074146600,
                1074213226,
                1074146632,
                1074146633,
                1074112808,
                805322189,
                1074248104,
                1074248105,
                1074214184,
                1074248106,
                1074214216,
                1074214217,
                1074178344,
                1074248107,
                1074214248,
                1074214249,
                1074179368,
                1074214250,
                1074179400,
                1074179401,
                1074112808,
                1074248108,
                1074214280,
                1074214281,
                1074180392,
                1074214282,
                1074180424,
                1074180425,
                1074145576,
                1074214283,
                1074180456,
                1074180457,
                1074146600,
                1074180458,
                1074146632,
                1074146633,
                1074112808
};
/*
const unsigned int lutIdx3[256] = {
                0,
                268435472,
                268435473,
                536871472,
                268435474,
                536871504,
                536871505,
                805325360,
                268435475,
                536871536,
                536871537,
                805326384,
                536871538,
                805326416,
                805326417,
                1074383408,
                268435476,
                536871568,
                536871569,
                805327408,
                536871570,
                805327440,
                805327441,
                1074416176,
                536871571,
                805327472,
                805327473,
                1074417200,
                805327474,
                1074417232,
                1074417233,
                1074383408,
                268435477,
                536871600,
                536871601,
                805328432,
                536871602,
                805328464,
                805328465,
                1074448944,
                536871603,
                805328496,
                805328497,
                1074449968,
                805328498,
                1074450000,
                1074450001,
                1074383408,
                536871604,
                805328528,
                805328529,
                1074450992,
                805328530,
                1074451024,
                1074451025,
                1074416176,
                805328531,
                1074451056,
                1074451057,
                1074417200,
                1074451058,
                1074417232,
                1074417233,
                1074383408,
                268435478,
                536871632,
                536871633,
                805329456,
                536871634,
                805329488,
                805329489,
                1074481712,
                536871635,
                805329520,
                805329521,
                1074482736,
                805329522,
                1074482768,
                1074482769,
                1074383408,
                536871636,
                805329552,
                805329553,
                1074483760,
                805329554,
                1074483792,
                1074483793,
                1074416176,
                805329555,
                1074483824,
                1074483825,
                1074417200,
                1074483826,
                1074417232,
                1074417233,
                1074383408,
                536871637,
                805329584,
                805329585,
                1074484784,
                805329586,
                1074484816,
                1074484817,
                1074448944,
                805329587,
                1074484848,
                1074484849,
                1074449968,
                1074484850,
                1074450000,
                1074450001,
                1074383408,
                805329588,
                1074484880,
                1074484881,
                1074450992,
                1074484882,
                1074451024,
                1074451025,
                1074416176,
                1074484883,
                1074451056,
                1074451057,
                1074417200,
                1074451058,
                1074417232,
                1074417233,
                1074383408,
                268435479,
                536871664,
                536871665,
                805330480,
                536871666,
                805330512,
                805330513,
                1074514480,
                536871667,
                805330544,
                805330545,
                1074515504,
                805330546,
                1074515536,
                1074515537,
                1074383408,
                536871668,
                805330576,
                805330577,
                1074516528,
                805330578,
                1074516560,
                1074516561,
                1074416176,
                805330579,
                1074516592,
                1074516593,
                1074417200,
                1074516594,
                1074417232,
                1074417233,
                1074383408,
                536871669,
                805330608,
                805330609,
                1074517552,
                805330610,
                1074517584,
                1074517585,
                1074448944,
                805330611,
                1074517616,
                1074517617,
                1074449968,
                1074517618,
                1074450000,
                1074450001,
                1074383408,
                805330612,
                1074517648,
                1074517649,
                1074450992,
                1074517650,
                1074451024,
                1074451025,
                1074416176,
                1074517651,
                1074451056,
                1074451057,
                1074417200,
                1074451058,
                1074417232,
                1074417233,
                1074383408,
                536871670,
                805330640,
                805330641,
                1074518576,
                805330642,
                1074518608,
                1074518609,
                1074481712,
                805330643,
                1074518640,
                1074518641,
                1074482736,
                1074518642,
                1074482768,
                1074482769,
                1074383408,
                805330644,
                1074518672,
                1074518673,
                1074483760,
                1074518674,
                1074483792,
                1074483793,
                1074416176,
                1074518675,
                1074483824,
                1074483825,
                1074417200,
                1074483826,
                1074417232,
                1074417233,
                1074383408,
                805330645,
                1074518704,
                1074518705,
                1074484784,
                1074518706,
                1074484816,
                1074484817,
                1074448944,
                1074518707,
                1074484848,
                1074484849,
                1074449968,
                1074484850,
                1074450000,
                1074450001,
                1074383408,
                1074518708,
                1074484880,
                1074484881,
                1074450992,
                1074484882,
                1074451024,
                1074451025,
                1074416176,
                1074484883,
                1074451056,
                1074451057,
                1074417200,
                1074451058,
                1074417232,
                1074417233,
                1074383408
};

const unsigned int lutIdx4[256] = {
                0,
                268435480,
                268435481,
                536871736,
                268435482,
                536871768,
                536871769,
                805333816,
                268435483,
                536871800,
                536871801,
                805334840,
                536871802,
                805334872,
                805334873,
                1074654008,
                268435484,
                536871832,
                536871833,
                805335864,
                536871834,
                805335896,
                805335897,
                1074686776,
                536871835,
                805335928,
                805335929,
                1074687800,
                805335930,
                1074687832,
                1074687833,
                1074654008,
                268435485,
                536871864,
                536871865,
                805336888,
                536871866,
                805336920,
                805336921,
                1074719544,
                536871867,
                805336952,
                805336953,
                1074720568,
                805336954,
                1074720600,
                1074720601,
                1074654008,
                536871868,
                805336984,
                805336985,
                1074721592,
                805336986,
                1074721624,
                1074721625,
                1074686776,
                805336987,
                1074721656,
                1074721657,
                1074687800,
                1074721658,
                1074687832,
                1074687833,
                1074654008,
                268435486,
                536871896,
                536871897,
                805337912,
                536871898,
                805337944,
                805337945,
                1074752312,
                536871899,
                805337976,
                805337977,
                1074753336,
                805337978,
                1074753368,
                1074753369,
                1074654008,
                536871900,
                805338008,
                805338009,
                1074754360,
                805338010,
                1074754392,
                1074754393,
                1074686776,
                805338011,
                1074754424,
                1074754425,
                1074687800,
                1074754426,
                1074687832,
                1074687833,
                1074654008,
                536871901,
                805338040,
                805338041,
                1074755384,
                805338042,
                1074755416,
                1074755417,
                1074719544,
                805338043,
                1074755448,
                1074755449,
                1074720568,
                1074755450,
                1074720600,
                1074720601,
                1074654008,
                805338044,
                1074755480,
                1074755481,
                1074721592,
                1074755482,
                1074721624,
                1074721625,
                1074686776,
                1074755483,
                1074721656,
                1074721657,
                1074687800,
                1074721658,
                1074687832,
                1074687833,
                1074654008,
                268435487,
                536871928,
                536871929,
                805338936,
                536871930,
                805338968,
                805338969,
                1074785080,
                536871931,
                805339000,
                805339001,
                1074786104,
                805339002,
                1074786136,
                1074786137,
                1074654008,
                536871932,
                805339032,
                805339033,
                1074787128,
                805339034,
                1074787160,
                1074787161,
                1074686776,
                805339035,
                1074787192,
                1074787193,
                1074687800,
                1074787194,
                1074687832,
                1074687833,
                1074654008,
                536871933,
                805339064,
                805339065,
                1074788152,
                805339066,
                1074788184,
                1074788185,
                1074719544,
                805339067,
                1074788216,
                1074788217,
                1074720568,
                1074788218,
                1074720600,
                1074720601,
                1074654008,
                805339068,
                1074788248,
                1074788249,
                1074721592,
                1074788250,
                1074721624,
                1074721625,
                1074686776,
                1074788251,
                1074721656,
                1074721657,
                1074687800,
                1074721658,
                1074687832,
                1074687833,
                1074654008,
                536871934,
                805339096,
                805339097,
                1074789176,
                805339098,
                1074789208,
                1074789209,
                1074752312,
                805339099,
                1074789240,
                1074789241,
                1074753336,
                1074789242,
                1074753368,
                1074753369,
                1074654008,
                805339100,
                1074789272,
                1074789273,
                1074754360,
                1074789274,
                1074754392,
                1074754393,
                1074686776,
                1074789275,
                1074754424,
                1074754425,
                1074687800,
                1074754426,
                1074687832,
                1074687833,
                1074654008,
                805339101,
                1074789304,
                1074789305,
                1074755384,
                1074789306,
                1074755416,
                1074755417,
                1074719544,
                1074789307,
                1074755448,
                1074755449,
                1074720568,
                1074755450,
                1074720600,
                1074720601,
                1074654008,
                1074789308,
                1074755480,
                1074755481,
                1074721592,
                1074755482,
                1074721624,
                1074721625,
                1074686776,
                1074755483,
                1074721656,
                1074721657,
                1074687800,
                1074721658,
                1074687832,
                1074687833,
                1074654008
};
*/
//#pragma HLS RESOURCE variable=lutIdx1 core=ROM_2P_BRAM
//#pragma HLS RESOURCE variable=lutIdx2 core=ROM_2P_BRAM

	ap_uint<32> de_val1=(ap_uint<32>)lutIdx1[opcode.range(7,0)];
	ap_uint<32> de_val2=(ap_uint<32>)lutIdx2[opcode.range(15,8)];
	ap_uint<32> de_val3=(ap_uint<32>)lutIdx1[opcode.range(23,16)];
	ap_uint<32> de_val4=(ap_uint<32>)lutIdx2[opcode.range(31,24)];
	uchar num1=(uchar)de_val1.range(31,28);
	uchar num2=(uchar)de_val2.range(31,28);
	uchar num3=(uchar)de_val3.range(31,28);
	uchar num4=(uchar)de_val4.range(31,28);

	ap_uint<DECODE_SIZE*5> idx1=de_val1.range(DECODE_SIZE*5-1,0);
	ap_uint<DECODE_SIZE*5> idx2=de_val2.range(DECODE_SIZE*5-1,0);
	ap_uint<DECODE_SIZE*5> idx3;
	ap_uint<DECODE_SIZE*5> idx4;
	for(int i=0;i<DECODE_SIZE;i++){
#pragma HLS UNROLL
		idx3.range(5*i+2,5*i)=de_val3.range(5*i+2,5*i);
		idx3.range(5*i+4,5*i+3)=(i<num3)?2:0;
		idx4.range(5*i+2,5*i)=de_val4.range(5*i+2,5*i);
		idx4.range(5*i+4,5*i+3)=(i<num4)?3:0;
	}


    ap_uint<DECODE_SIZE*5> idx1_ext_shift=idx1;
    ap_uint<DECODE_SIZE*5> idx2_ext_shift;
    if(num1<DECODE_SIZE){
    	idx2_ext_shift=idx2<<(num1*5);
    }
    else{
    	idx2_ext_shift=0;
    }
    ap_uint<DECODE_SIZE*5> idx3_ext_shift;
    if(num1+num2<DECODE_SIZE){
    	idx3_ext_shift=idx3<<((num1+num2)*5);
    }
    else{
    	idx3_ext_shift=0;
    }
    ap_uint<DECODE_SIZE*5> idx4_ext_shift;
    if(num1+num2+num3<DECODE_SIZE){
    	idx4_ext_shift=idx4<<((num1+num2+num3)*5);
    }
    else{
    	idx4_ext_shift=0;
    }
    shuffled_type32 data;
    data.idx=idx1_ext_shift|idx2_ext_shift|idx3_ext_shift|idx4_ext_shift;
    data.num=num1+num2+num3+num4;
    return data;
}

#endif /*  __FPGA_DECODER32_H__ */
